package algebra.visitors.cursors;

import utils.exception.CoreReasoningException;
import kb.DescriptionLogicsKB;
import algebra.query.indexing.DescriptionIndex;
import algebra.query.indexing.IndexTreeNode;
import entities.Individual;
import entities.assertion.ConceptAssertion;
import entities.concept.Concept;

public class CACursorDITraversal extends CACursorDI {

	private boolean init;
	private IndexTreeNode cur;
	private final boolean notest;
	
	public CACursorDITraversal(DescriptionIndex di, ConceptAssertion ca, Concept d, boolean noTest) {
		super(di, ca, di.getRoot(), false, d);
		notest = noTest;
	}

	@Override
	public boolean openCursor() {
		init = false;
		cur = null;
		return false;
	}
	
	@Override
	public ConceptAssertion getNextResult() {
		if (ca == null) {
			return null;
		}
		IndexTreeNode res = getNextNode();
		if (res != null) {
			return res.getNodeAssertion();
		}
		return null;
	}
	
	private IndexTreeNode getNextNode(){
		if(!init){
			cur = this.di.getThreadedFirst();
			init = true;
		}else{
			if(cur != null){
				cur = this.di.getThreadedNext(cur);
			}
		}
		//test condition
		if(!notest){
			try {
				if(cur == null){
					return null;
				}
				boolean answer = isAnswer(this.ca, cur, null);
				while(!answer && cur!=null){
//					cur = this.getNextNode();
					cur = this.di.getThreadedNext(cur);
					answer = isAnswer(this.ca, cur, null);
				}
			} catch (CoreReasoningException e) {
				e.printStackTrace();
			}
		}
		return cur;
	}

	private boolean isAnswer(ConceptAssertion q, IndexTreeNode node, DescriptionLogicsKB kb) throws CoreReasoningException{
		if(node==null){
			return false;
		}
		ConceptAssertion na = node.getNodeAssertion();
		if(DescriptionIndex.SAME_IND_RESTRICTION){
			if(!q.getIndividual().equals(Individual.getStarIndividual())&& !q.getIndividual().equals(na.getIndividual())){
				return false;
			}
		}
		ConceptAssertion starfix = new ConceptAssertion(na.getIndividual(), q.getConcept());
		return DescriptionIndex.isQualifiedAnswerToQuery(starfix, node, kb);
	}
	
}
